package com.ygqh.baby.shiro.session;

import java.io.Serializable;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.web.servlet.ShiroHttpSession;

public class ShiroSessionUtil {

	public static Serializable getSessionId(ServletRequest request, ServletResponse response) {
		return getReferencedSessionId(request, response);
	}

	private static Serializable getReferencedSessionId(ServletRequest request, ServletResponse response) {
		String id = getSessionIdCookieValue(request);
		if (id != null) {
			return id;
		}
		id = getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
		if (id != null) {
			return id;
		}
		id = request.getParameter(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
		return id;
	}

	private static String getUriPathSegmentParamValue(ServletRequest servletRequest, String paramName) {
        if (!(servletRequest instanceof HttpServletRequest)) {
            return null;
        }
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        String uri = request.getRequestURI();
        if (uri == null) {
            return null;
        }
        int queryStartIndex = uri.indexOf('?');
        if (queryStartIndex >= 0) { //get rid of the query string
            uri = uri.substring(0, queryStartIndex);
        }
        int index = uri.indexOf(';'); //now check for path segment parameters:
        if (index < 0) {
            //no path segment params - return:
            return null;
        }
        //there are path segment params, let's get the last one that may exist:
        final String TOKEN = paramName + "=";
        uri = uri.substring(index+1); //uri now contains only the path segment params
        //we only care about the last JSESSIONID param:
        index = uri.lastIndexOf(TOKEN);
        if (index < 0) {
            //no segment param:
            return null;
        }
        uri = uri.substring(index + TOKEN.length());
        index = uri.indexOf(';'); //strip off any remaining segment params:
        if(index >= 0) {
            uri = uri.substring(0, index);
        }
        return uri; //what remains is the value
	}

	private static String getSessionIdCookieValue(ServletRequest servletRequest) {
        if (!(servletRequest instanceof HttpServletRequest)) {
            return null;
        }
		HttpServletRequest request = (HttpServletRequest)servletRequest;
		Cookie[] cookies = request.getCookies();
		if (cookies == null || cookies.length == 0) {
			return null;
		}
		for (Cookie cookie : cookies) {
			if (cookie.getName().equals(ShiroHttpSession.DEFAULT_SESSION_ID_NAME)) {
				return cookie.getValue();
			}
		}
		return null;
	}

}
